//==============================================================================
//
//               Copyright (C) 2002  Dick van Oudheusden
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2004-07-17 12:15:22 $ $Revision: 1.3 $
//
//==============================================================================

#include <stdlib.h>

#include "ofc/config.h"

#include "ofc/DText.h"
#include "ofc/DList.h"

#include "DInc.h"
#include "DTest.h"

//-Collections-----------------------------------------------------------------

void DList_test()
{
  DList         *list;
  DListIterator *iter;
  DInc          *obj;
  DInc          *nxt;
  int            cnt;
  DList         *sub;
  DText         *txt;
  DInc          *obj1;
  DInc          *obj2;
  DInc          *obj3;
  
  STARTTEST();
  
  list = [[DList alloc] init];

  TEST([list isEmpty]);
  TEST([list length] == 0);

  [DInc reset];
  
  obj = [DInc new];

  [list append :obj];

  TEST([list length] == 1);
  TEST(![list isEmpty]);
  TEST([list has :obj]);

  [list append :obj];

  TEST([list count :obj] == 2);
  
  nxt = [DInc new];

  TEST(![list has :nxt]);

  [list insert :1 :nxt];
  
  TEST([list length] == 3);
  
  [list delete :0];
   

  for (cnt = 0; cnt < 5; cnt++)
    [list append :[DInc new]];
  
  TEST([list has :nxt]);
  TEST([list count :obj] == 1);
  TEST([list get :1] == obj);
 
  [list reverse];
   
  TEST([list index  :obj] == 5);
  TEST([list rindex :nxt] == 6);

  TEST([list pop] == nxt);
  [nxt free];

  nxt = [DInc new];

  [list prepend :nxt];

  TEST([list remove :obj]);

  [obj free];

  obj = [DInc new];

  obj = [list set :2 :obj];
  [obj free];

  for (cnt = 0; cnt < 5; cnt++)
    [list insert :6 :[DInc new]];

  sub = [list get :3 :8];
#if 0
  [list each :@selector(print)];
  [sub  each :@selector(print)];
#endif
  
  iter = [[DListIterator alloc] init];

  [iter list :sub];

  TEST([[iter first] number] == 5);
  
  TEST([[iter next]  number] == 4);
  
  obj = [DInc new];
  
  [iter after :obj];
  
  TEST([[iter object] number] == 15);
       
  TEST([[iter last]  number] == 12);

  TEST([[iter prev]  number] == 13);

  obj = [DInc new];
  
  [iter before :obj];
  
  TEST([[iter object] number] == 16);
  
  obj = [iter object];
  TEST([iter object :obj] == obj);

  [iter free];
  
  [sub shallowFree];

  [list each :@selector(number)];

  [list free];

  // stack methods test
  list = [DList new];
  
  obj1 = [DInc new];
  obj2 = [DInc new];
  obj3 = [DInc new];
  
  TEST([list push :obj1]);
  TEST(![list isEmpty]);
  TEST([list push :obj2]);
  TEST([list push :obj3]);
  
  TEST([list length] == 3);
  
  TEST([list tos] == obj3);
  
  TEST([list pop] == obj3);
  TEST([list pop] == obj2);
  TEST([list pop] == obj1);
  
  TEST([list length] == 0);
  TEST([list pop] == nil);
  TEST([list tos] == nil);
 
  // queue methods test
  TEST([list enqueue :obj1]);
  TEST(![list isEmpty]);
  TEST([list enqueue :obj2]);
  TEST([list enqueue :obj3]);
  
  TEST([list length] == 3);
  
  TEST([list dequeue] == obj1);
  TEST([list dequeue] == obj2);
  TEST([list dequeue] == obj3);
  
  TEST([list length] == 0);
  TEST([list dequeue] == nil);

  [obj1 free];
  [obj2 free];
  [obj3 free];
  
  [list free];
  
  // string methods test
  list = [DList split :"Hello, this      is a test of the splitter" :' ' :6];

  TEST([list length] == 7);

  txt = [list join :'?'];
 
  TEST([txt ccompare :"Hello,?this?is?a?test?of?the splitter"] == 0);
 
  [txt free];
  
  [list delete :1 :4];
  
  txt = [list join :' '];
  
  TEST([txt ccompare :"Hello, of the splitter"] == 0);
   
  [list free];
   
  STOPTEST();
}

